package com.smart.tool.context;

import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * @Author gao.gwq
 * @Version SmartContext.java, v 0.1 2024年06月06日 16:57 gao.gwq
 * @Description: TODO
 */
public class SmartContext implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    public static Class<?> loadClass(String clazz) {
        try {
            return Class.forName(clazz);
        } catch (Throwable e) {
            String message = "can not find class["+clazz+"]";
            throw new FatalBeanException(message, e);
        }
    }


    /**
     * 从spring容器获取Bean
     */
    public static <T> T getSpringBean(String name) {
        if (StringUtils.isBlank(name)) {
            return null;
        }
        return (T) applicationContext.getBean(name);
    }

    /**
     * 获取Spring的Bean
     */
    public static <T> T getSpringBean(Class<T> type) {
        if (applicationContext ==null) {
            return null;
        }
        try {
            Map<String, T> beanMap = applicationContext.getBeansOfType(type);
            if (beanMap.size() == 1) {
                return beanMap.values().stream().findFirst().get();
            } else if (beanMap.size() > 1) {
                return beanMap.values().stream().filter(it->it.getClass().equals(type)).findFirst().orElse(null);
            }
            return null;
        } catch(Throwable ignored) {
            return null;
        }
    }

    /**
     * 获取Spring的Bean
     */
    public static <T> Map<String, T> getSpringBeans(Class<T> type) {
        if (applicationContext ==null) {
            return null;
        }
        try {
            return applicationContext.getBeansOfType(type);
        } catch(Throwable ignored) {
            return null;
        }
    }

    public static Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotation) {
        if (applicationContext ==null) {
            return null;
        }
        try {
            return applicationContext.getBeansWithAnnotation(annotation);
        } catch(Throwable ignored) {
            return null;
        }
    }




    public static String resolve(String value) {
        return applicationContext.getEnvironment().resolvePlaceholders(value);
    }

    private static void init(ApplicationContext context) {
        applicationContext = context;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 通过class获取bean name
     * @param clz
     * @return
     */
    public static String getBeanName(Class<?> clz) {
        String clzName = Objects.isNull(clz) ? null : clz.getSimpleName();
        if (StringUtils.isEmpty(clzName)) {
            return null;
        }
        return clzName.substring(0, 1).toLowerCase() + clzName.substring(1);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        init(applicationContext);
    }
}
